package edu.upenn.cis.cis550.hw3.client;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

import com.google.gwt.core.client.EntryPoint;

import com.google.gwt.core.client.GWT;

import com.google.gwt.core.client.JavaScriptObject;

import com.google.gwt.dom.client.Style.Unit;

import com.google.gwt.json.client.JSONObject;

import com.google.gwt.user.client.Window;

import com.google.gwt.user.client.rpc.AsyncCallback;

import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.LayoutPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SplitLayoutPanel;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.TabLayoutPanel;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

import com.google.gwt.user.client.ui.DockLayoutPanel;

import com.google.gwt.user.client.ui.FlexTable;

import com.google.gwt.user.client.ui.Grid;

import com.google.gwt.user.client.ui.HTML;

import com.google.gwt.user.client.ui.HorizontalPanel;

import com.google.gwt.user.client.ui.Image;

import com.google.gwt.user.client.ui.Label;

import com.google.gwt.user.client.ui.PopupPanel;

import com.google.gwt.user.client.ui.RootLayoutPanel;

import com.google.gwt.user.client.ui.ScrollPanel;

import com.google.gwt.user.client.ui.VerticalPanel;

import com.google.gwt.xml.client.Node;

import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;

import com.google.gwt.event.dom.client.ClickHandler;

import edu.upenn.cis.cis550.hw3.shared.Relation;

import edu.upenn.cis.cis550.hw3.shared.Tuple;

/**
 * 
 * This is the main class for generating Web table results for CIS 550 HW1
 * 
 * 
 * 
 * @author zives
 * 
 * 
 */

public class testHomepage2 implements EntryPoint {
    private final QueryTablesAsync queryService = GWT.create(QueryTables.class);

    private final QueryRecomAsync recomService = GWT.create(QueryRecom.class);

    private final UpdateTablesAsync updateService = GWT
            .create(UpdateTables.class);

    private final QueryExportAsync exportService = GWT
            .create(QueryExport.class);

    int userid = 0;

    private JavaScriptObject theGraph;

    /**
     * 
     * Initialize layout widgets
     */

    VerticalPanel loginPanel = new VerticalPanel();

    LayoutPanel headerBar = new LayoutPanel();

    Button gotoHome = new Button("Home");

    HorizontalPanel footerBar = new HorizontalPanel();

    Button gotoTopPhotos = new Button("Top Photos");

    Button gotoFriends = new Button("Friends");

    Button gotoFriendNetwork = new Button("Network");

    Button gotoSearch = new Button("Search");

    Button gotoAddPhoto = new Button("Add a photo");

    LayoutPanel feedBar = new LayoutPanel();

    VerticalPanel recentUpdates = new VerticalPanel();

    ScrollPanel recentUpdatesScrollPanel = new ScrollPanel();
    
    ScrollPanel recomScrollPanel = new ScrollPanel();

    FlexTable recomTable = new FlexTable();

    LayoutPanel centerContent = new LayoutPanel();

    // userPage

    LayoutPanel userPage = new LayoutPanel();
    
    SplitLayoutPanel userContent = new SplitLayoutPanel();

    HorizontalPanel userHeaderBar = new HorizontalPanel();

    VerticalPanel userInfoColumn = new VerticalPanel();

    VerticalPanel userPhotos = new VerticalPanel();

    ScrollPanel userPhotosScrollPanel = new ScrollPanel();

    FlexTable userInfoTable = new FlexTable();

    // topPhotos

    Grid topPhotos = new Grid(5, 2);
    
    ScrollPanel topPhotosScrollPanel = new ScrollPanel();

    MultiWordSuggestOracle oracle;

    // friendList

    VerticalPanel friendList = new VerticalPanel();

    ScrollPanel friendListScrollPanel = new ScrollPanel();

    // friendNetwork

    HTML friendNetwork = new HTML("<div id=\"infoVis\"></div>");

    final DialogBox signupBox = new DialogBox();

    // search
    VerticalPanel searchPanel = new VerticalPanel();

    // add photo
    VerticalPanel addPhotoPanel = new VerticalPanel();
    
    //login
    MultiWordSuggestOracle profOracle;
    HashMap<String,String> profMap;

    // This is the entry point method.

    public void onModuleLoad() {
        if (userid == 0) {
            drawLoginPage();
        } else {
            drawHomepage();
        }
    }

    protected void loadUserPage(final int friendID) {

        userHeaderBar.clear();
        userInfoTable.removeAllRows();
        userPhotos.clear();

        AsyncCallback<Relation> callbackUser = new AsyncCallback<Relation>() {

            public void onFailure(Throwable caught) {

            }

            public void onSuccess(Relation r) {
                Tuple t = r.iterator().next();
                String firstName = t.getValue("firstName").toString();
                String lastName = t.getValue("lastName").toString();
                String dob = t.getValue("dateBirth").toString();
                String email = t.getValue("email").toString();
                String gender = t.getValue("gender").toString();

                userHeaderBar.add(new Label(firstName + " " + lastName));

                userInfoTable.setText(0, 0, "Date of Birth");
                userInfoTable.setText(0, 1, dob);
                userInfoTable.setText(1, 0, "Email");
                userInfoTable.setText(1, 1, email);
                userInfoTable.setText(2, 0, "Gender");
                userInfoTable.setText(2, 1, gender);

                System.out.println("adding");
                centerContent.clear();
                centerContent.add(userPage);
            }
        };

        AsyncCallback<Relation> callbackStudent = new AsyncCallback<Relation>() {

            public void onFailure(Throwable caught) {

            }

            public void onSuccess(Relation r) {
                if (r.iterator().hasNext()) {
                    Tuple t = r.iterator().next();
                    String year = t.getValue("year").toString();
                    String major = t.getValue("major").toString();
                    String gpa = t.getValue("GPA").toString();
                    String college = t.getValue("academicInstitution")
                            .toString();

                    LinkedHashMap<String, String> userInfoList = new LinkedHashMap<String, String>();
                    userInfoList.put("Year", year);
                    userInfoList.put("Major", major);
                    userInfoList.put("GPA", gpa);
                    userInfoList.put("College", college);

                    for (Map.Entry<String, String> e : userInfoList.entrySet()) {
                        if (!e.getValue().equals("")) {
                            int row = userInfoTable.getRowCount();
                            userInfoTable.setText(row, 0, e.getKey());
                            userInfoTable.setText(row, 1, e.getValue());
                        }
                    }
                }
            }
        };

        AsyncCallback<Relation> callbackProfessor = new AsyncCallback<Relation>() {

            public void onFailure(Throwable caught) {

            }

            public void onSuccess(Relation r) {
                if (r.iterator().hasNext()) {
                    Tuple t = r.iterator().next();
                    String roomNumber = t.getValue("roomNumber").toString();
                    String researchArea = t.getValue("researchArea").toString();
                    String title = t.getValue("title").toString();
                    String college = t.getValue("academicInstitution")
                            .toString();

                    LinkedHashMap<String, String> userInfoList = new LinkedHashMap<String, String>();
                    userInfoList.put("Title", title);
                    userInfoList.put("Room", roomNumber);
                    userInfoList.put("Research Area", researchArea);
                    userInfoList.put("College", college);

                    for (Map.Entry<String, String> e : userInfoList.entrySet()) {
                        if (!e.getValue().equals("")) {
                            int row = userInfoTable.getRowCount();
                            userInfoTable.setText(row, 0, e.getKey());
                            userInfoTable.setText(row, 1, e.getValue());
                        }
                    }
                }
            }
        };

        AsyncCallback<Relation> callbackPhoto = new AsyncCallback<Relation>() {

            public void onFailure(Throwable caught) {

            }

            public void onSuccess(Relation r) {
                Iterator<Tuple> i = r.iterator();
                while (i.hasNext()) {
                    Tuple t = i.next();
                    String photoID = t.getValue("photoID").toString();
                    String url = t.getValue("url").toString();
                    String description = t.getValue("description").toString();
                    VerticalPanel photo = buildPhotoFrame(friendID, url,
                            description);
                    System.out.println("adding " + photoID);
                    userPhotos.add(photo);
                }
            }
        };

        queryService.getUserInfo(Integer.toString(friendID), callbackUser);
        queryService
                .getStudentInfo(Integer.toString(friendID), callbackStudent);
        queryService.getProfessorInfo(Integer.toString(friendID),
                callbackProfessor);
        exportService.getUsersPhotos(Integer.toString(friendID), callbackPhoto);

    }

    private void loadRecentUpdates() {

        //recentUpdates.setWidth("50px");

        AsyncCallback<Relation> callback = new AsyncCallback<Relation>() {

            public void onFailure(Throwable caught) {

            }

            public void onSuccess(Relation r) {

                Iterator<Tuple> iter = r.iterator();

                // System.out.println(i.next().getValue("finalScore"));

                for (int i = 0; i < 10; i++) {

                    if (iter.hasNext()) {

                        Tuple t = iter.next();

                        int pid = Integer.parseInt(t.getValue("photoID")
                                .toString());
                        String url = t.getValue("url").toString();
                        String name = t.getValue("firstName").toString() + " "
                                + t.getValue("lastName").toString();
                        VerticalPanel p = buildPhotoFrame(pid, url, "Uploaded by " + name);
                        p.setHeight("100px");

                        // Image im = new Image();

                        // im.setUrl(url);

                        // p.add(im);
                        /*
                         * p.setTitle("uploaded by " +
                         * t.getValue("firstName").toString() +
                         * 
                         * " " + t.getValue("lastName").toString());
                         */

                        recentUpdates.add(p);
                        /*
                         * System.out.println("Putting " + im.getUrl()
                         * 
                         * + " in panel fromm user "
                         * 
                         * + t.getValue("firstName").toString() + " " +
                         * t.getValue("lastName").toString());
                         */

                    }

                }

            }

        };

        queryService.getRecentUpdates(Integer.toString(userid), callback);

    }

    private void loadFriendRecommendations() {

        // recentUpdates.setWidth("50px");

        AsyncCallback<Relation> callback = new AsyncCallback<Relation>() {

            public void onFailure(Throwable caught) {
                // System.out.println(caught.toString());
                System.out.println("Failure");
                caught.printStackTrace();
            }

            public void onSuccess(Relation result) {
                if (!result.isEmpty()) {
                    Iterator<Tuple> i = result.iterator();
                    while (i.hasNext()) {
                        int rows = recomTable.getRowCount();
                        final Tuple t = i.next();
                        final String fid = t.getValue("recomID").toString();

                        String name = t.getValue("firstName").toString() + " "
                                + t.getValue("lastName").toString();
                        // System.out.println(name);
                        // String name = t.getValue(0).toString();
                        // System.out.println(t.getSchema().toString());

                        // String name = t.getValue("recomID").toString();
                        Button b = new Button("Add friend");
                        b.addClickHandler(new ClickHandler() {

                            public void onClick(ClickEvent event) {
                                Button b = (Button) event.getSource();
                                addFriend(fid);
                                b.setText("Added!");
                                b.setEnabled(false);

                            }
                        });

                        recomTable.setText(rows, 0, name);
                        recomTable.setWidget(rows, 1, b);

                    }
                } else {
                    System.out.println("empty set");
                }

            }
        };

        System.out.println("calling allFriendsRecom");

        recomService.getAllFriendRecom(Integer.toString(userid), callback);

    }

    private void loadTopPhotos() {

        topPhotos.clear();

        topPhotos.setSize("100%", "100%");

        // topPhotos.setWidth("100%");

        // topPhotos.setHeight("100%");

        // topPhotos.addStyleName("topPhotosGrid");

        // topPhotos.getColumnFormatter().setWidth(0, "20px");

        AsyncCallback<Relation> callback = new AsyncCallback<Relation>() {

            public void onFailure(Throwable caught) {

            }

            public void onSuccess(Relation r) {

                Iterator<Tuple> i = r.iterator();

                // System.out.println(i.next().getValue("finalScore"));

                for (int row = 0; row < topPhotos.getRowCount(); row++) {

                    for (int col = 0; col < topPhotos.getColumnCount(); col++) {

                        if (i.hasNext()) {

                            Tuple t = i.next();

                            // VerticalPanel p = new VerticalPanel();

                            //Image im = new Image();
                            
                            int photoID = Integer.parseInt(t.getValue("photoID").toString());

                            String url = t.getValue("url").toString();
                            
                            String score = t.getValue("finalScore").toString();

                            //im.setUrl(url);
                            //im.setSize("100%", "100%");
                            //im.setTitle(t.getValue("finalScore").toString());

                            // String html = "<img src=\"" +

                            // t.getValue("url").toString() + "\"/>";

                            // System.out.println(html);

                            // p.add(im);

                            // p.setTitle(t.getValue("finalScore").toString());

                            topPhotos.setWidget(row, col, buildPhotoFrame(photoID, url, score));

                            /*
                            System.out.println("Putting " + im.getUrl()

                            + " in row " + row + " and col " + col

                            + " with score "

                            + t.getValue("finalScore").toString());
                            */
                        }

                    }
                }
                centerContent.clear();

                centerContent.add(topPhotosScrollPanel);

            }

        };

        queryService.getTopScoringPhotos(Integer.toString(userid), callback);

    }

    protected void loadFriends() {

        AsyncCallback<Relation> callback = new AsyncCallback<Relation>() {

            public void onFailure(Throwable caught) {

            }

            public void onSuccess(Relation r) {

                Iterator<Tuple> i = r.iterator();

                friendList.clear();
                
                friendList.add(new Label("Friends"));

                while (i.hasNext()) {

                    Tuple friend = i.next();

                    String firstname = friend.getValue("FirstName").toString();

                    String lastname = friend.getValue("LastName").toString();

                    final Integer friendid = Integer.parseInt(friend.getValue(
                            "friendID").toString());

                    Button l = new Button(firstname + " " + lastname);

                    l.addClickHandler(new ClickHandler() {

                        public void onClick(ClickEvent event) {

                            System.out.println(friendid);
                            loadUserPage(friendid);

                        }

                    });

                    friendList.add(l);

                }

                centerContent.clear();

                centerContent.add(friendListScrollPanel);

            }

        };

        queryService.getFriends(userid, callback);

    }

    private void loadFriendNetwork() {

        friendNetwork.addStyleName("infoVis");

        centerContent.clear();
        
        //centerContent.add(getCircleBrowser());

        centerContent.add(friendNetwork);

        getFirstPerson();

    }

    private void loadSearch() {
        centerContent.clear();
        refreshSearchPanel();
        centerContent.add(searchPanel);

    }

    protected void loadAddPhoto() {
        centerContent.clear();
        refreshAddPhoto();
        centerContent.add(addPhotoPanel);

    }

    private void refreshAddPhoto() {
        final TextBox url = new TextBox();
        final TextBox description = new TextBox();
        Button upload = new Button("Add Photo");
        final HashMap<String, String> namesToIDs = new HashMap<String, String>();

        final HorizontalPanel result = new HorizontalPanel();
        result.setVisible(false);

        final ListBox visibility = new ListBox();
        visibility.addItem("Everyone");
        visibility.addItem("Only these users");
        visibility.addItem("Only these circles");
        visibility.setVisibleItemCount(1);

        final FlowPanel choices = new FlowPanel();
        choices.setVisible(false);

        visibility.addChangeHandler(new ChangeHandler() {

            public void onChange(ChangeEvent event) {
                if (visibility.getSelectedIndex() == 0) {
                    choices.setVisible(false);
                } else if (visibility.getSelectedIndex() == 1) {
                    choices.clear();
                    queryService.getFriends(userid,
                            new AsyncCallback<Relation>() {

                                public void onFailure(Throwable caught) {
                                }

                                public void onSuccess(Relation result) {
                                    Iterator<Tuple> i = result.iterator();
                                    while (i.hasNext()) {
                                        Tuple t = i.next();
                                        String name = t.getValue("FirstName")
                                                .toString()
                                                + " "
                                                + t.getValue("LastName")
                                                        .toString();
                                        CheckBox c = new CheckBox(name);
                                        choices.add(c);
                                        namesToIDs.put(name,
                                                t.getValue("friendID")
                                                        .toString());
                                    }
                                    choices.setVisible(true);
                                }

                            });
                } else if (visibility.getSelectedIndex() == 2) {
                    choices.clear();
                    queryService.getCirclesInfo(Integer.toString(userid),
                            new AsyncCallback<Relation>() {

                                public void onFailure(Throwable caught) {
                                }

                                public void onSuccess(Relation result) {
                                    Iterator<Tuple> i = result.iterator();
                                    while (i.hasNext()) {
                                        Tuple t = i.next();
                                        String name = t.getValue("name")
                                                .toString();
                                        CheckBox c = new CheckBox(name);
                                        choices.add(c);
                                        namesToIDs.put(name,
                                                t.getValue("circleID")
                                                        .toString());
                                    }
                                    choices.setVisible(true);
                                }

                            });
                }

            }
        });

        Grid g = new Grid(3, 2);
        g.setText(0, 0, "URL:");
        g.setWidget(0, 1, url);
        g.setText(1, 0, "Description:");
        g.setWidget(1, 1, description);
        g.setText(2, 0, "Visibility:");
        g.setWidget(2, 1, visibility);

        url.addKeyUpHandler(new KeyUpHandler() {

            public void onKeyUp(KeyUpEvent event) {
                if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
                    // addPhoto(url.getText(), description.getText(), result);
                }
            }
        });
        upload.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {
                //Window.alert(Integer.toString(visibility.getSelectedIndex()));
                addPhoto(url.getText(), description.getText(),
                        visibility.getSelectedIndex(), namesToIDs, choices,
                        result);
            }
        });

        addPhotoPanel.add(g);
        addPhotoPanel.add(choices);
        addPhotoPanel.add(upload);
        addPhotoPanel.add(result);
    }

    private void addPhoto(String url, String description, int visibility,
            HashMap<String, String> dict, FlowPanel choices,
            final HorizontalPanel resultPanel) {

        ArrayList<String> vis = new ArrayList<String>();
        for (int i = 0; i < choices.getWidgetCount(); i++) {
            if (choices.getWidget(i) instanceof CheckBox) {
                CheckBox c = (CheckBox) choices.getWidget(i);
                if (c.getValue()) {
                    String name = c.getText();
                    vis.add(dict.get(name));
                }
            }

        }

        AsyncCallback<String> callback = new AsyncCallback<String>() {

            public void onSuccess(String result) {
                Label l = new Label();
                l.setText(result);
                resultPanel.add(l);
                resultPanel.setVisible(true);

            }

            public void onFailure(Throwable caught) {
                // TODO Auto-generated method stub

            }
        };

        updateService.addPhoto(userid, url, description, "0", visibility, vis,
                callback);
    }

    private void drawLoginPage() {

        HorizontalPanel buttons = new HorizontalPanel();
        final Button loginButton = new Button("Log in");
        final Button signupButton = new Button("Sign Up");
        final TextBox nameField = new TextBox();
        final PasswordTextBox passField = new PasswordTextBox();
        final Label errorLabel = new Label();
        final Grid loginGrid = new Grid(2, 2);
        final Image im = new Image("Upic_logo.png");

        // We can add style names to widgets
        loginButton.addStyleDependentName("login");
        signupButton.addStyleDependentName("login");

        loginGrid.setText(0, 0, "Username:");
        loginGrid.setWidget(0, 1, nameField);
        loginGrid.setText(1, 0, "Password:");
        loginGrid.setWidget(1, 1, passField);
        loginGrid.addStyleName("loginGrid");
        loginGrid.getColumnFormatter().setStyleName(1, "fieldColumn");

        buttons.add(signupButton);
        buttons.add(loginButton);

        // Create the Signup Box
        profOracle = new MultiWordSuggestOracle();
        
        queryService.getProfessors(new AsyncCallback<Relation>() {
            
            public void onSuccess(Relation result) {
                Iterator<Tuple> i = result.iterator();
                while(i.hasNext()) {
                    Tuple t = i.next();
                    String name = t.getValue("firstName").toString() + " " + t.getValue("lastName").toString();
                    String id = t.getValue("professorID").toString();
                    profOracle.add(name);
                    profMap.put(name, id);
                }
                
            }

            public void onFailure(Throwable caught) {
                // TODO Auto-generated method stub
                
            }
            

        });

        final DialogBox signupBox = getSignUpBox();

        loginPanel.setWidth("100%");
        loginPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
        loginPanel.add(im);
        loginPanel.add(loginGrid);
        loginPanel.add(buttons);
        loginPanel.add(errorLabel);

        RootPanel.get("mainPanel").add(loginPanel);

        // Focus the cursor on the name field when the app loads
        nameField.setFocus(true);
        nameField.selectAll();

        signupButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                signupBox.show();
                // loginButton.setEnabled(false);
                loginButton.setFocus(true);
            }
        });

        loginButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                login(nameField.getText(), passField.getText());
            }
        });
    }

    private void login(final String user, String pass) {
        AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {
            public void onFailure(Throwable caught) {

            }

            public void onSuccess(Boolean loginConfirmed) {

                if (loginConfirmed) {
                    userid = Integer.parseInt(user);
                    loginPanel.clear();
                    drawHomepage();
                } else {
                    Window.alert("Login Incorrect!");
                }
            }
        };

        System.out.println("Password: " + pass);

        queryService.validatePassword(user, pass, callback);
    }

    private DialogBox getSignUpBox() {
        final HorizontalPanel closeButtonPanel = new HorizontalPanel();
        closeButtonPanel.setWidth("100%");
        closeButtonPanel
                .setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
        final Button closeButton = new Button("x");
        closeButton.addStyleName("littleX");
        closeButtonPanel.add(closeButton);

        final Button signupButton = new Button("Sign Up!");
        final Grid signupGrid = new Grid(6, 2);
        final VerticalPanel signupPanel = new VerticalPanel();
        final Grid stuProfGrid = new Grid(5, 2);
        final ListBox stuProf = new ListBox();
        final VerticalPanel stuProfOptions = new VerticalPanel();
        stuProf.addItem("Student");
        stuProf.addItem("Prof");

        final TextBox firstName = new TextBox();
        final TextBox lastName = new TextBox();
        final TextBox email = new TextBox();
        final TextBox dob = new TextBox();
        final TextBox gender = new TextBox();

        final TextBox year = new TextBox();
        final TextBox major = new TextBox();
        final TextBox GPA = new TextBox();
        final TextBox studentCollege = new TextBox();
        final SuggestBox profSuggest = new SuggestBox(profOracle);
        profSuggest.setWidth("100%");

        stuProfGrid.setText(0, 0, "Year: ");
        stuProfGrid.setWidget(0, 1, year);
        stuProfGrid.setText(1, 0, "Major: ");
        stuProfGrid.setWidget(1, 1, major);
        stuProfGrid.setText(2, 0, "GPA: ");
        stuProfGrid.setWidget(2, 1, GPA);
        stuProfGrid.setText(3, 0, "Academic Institution: ");
        stuProfGrid.setWidget(3, 1, studentCollege);
        stuProfGrid.setText(4, 0, "Advisor: ");
        stuProfGrid.setWidget(4, 1, profSuggest);

        final TextBox office = new TextBox();
        final TextBox researchArea = new TextBox();
        final TextBox title = new TextBox();
        final TextBox professorCollege = new TextBox();

        stuProf.addChangeHandler(new ChangeHandler() {

            public void onChange(ChangeEvent event) {
                if (stuProf.getSelectedIndex() == 0) {
                    stuProfGrid.setText(0, 0, "Year: ");
                    stuProfGrid.setWidget(0, 1, year);
                    stuProfGrid.setText(1, 0, "Major: ");
                    stuProfGrid.setWidget(1, 1, major);
                    stuProfGrid.setText(2, 0, "GPA: ");
                    stuProfGrid.setWidget(2, 1, GPA);
                    stuProfGrid.setText(3, 0, "Academic Institution: ");
                    stuProfGrid.setWidget(3, 1, studentCollege);
                    stuProfGrid.setText(4, 0, "Advisor: ");
                    stuProfGrid.setWidget(4, 1, profSuggest);
                } else {
                    
                    stuProfGrid.setText(0, 0, "Office: ");
                    stuProfGrid.setWidget(0, 1, office);
                    stuProfGrid.setText(1, 0, "Research Area: ");
                    stuProfGrid.setWidget(1, 1, researchArea);
                    stuProfGrid.setText(2, 0, "Title: ");
                    stuProfGrid.setWidget(2, 1, title);
                    stuProfGrid.setText(3, 0, "Academic Institution: ");
                    stuProfGrid.setWidget(3, 1, professorCollege);
                    stuProfGrid.setText(4,0,"");
                    stuProfGrid.setText(4, 1, "");
                }

            }

        });
        stuProf.setVisibleItemCount(1);

        signupGrid.setText(0, 0, "First Name: ");
        signupGrid.setWidget(0, 1, firstName);
        signupGrid.setText(1, 0, "Last Name: ");
        signupGrid.setWidget(1, 1, lastName);
        signupGrid.setText(2, 0, "Email: ");
        signupGrid.setWidget(2, 1, email);
        signupGrid.setText(3, 0, "Date of Birth: ");
        signupGrid.setWidget(3, 1, dob);
        signupGrid.setText(4, 0, "Gender: ");
        signupGrid.setWidget(4, 1, gender);
        signupGrid.setText(5, 0, "User Type:");
        signupGrid.setWidget(5, 1, stuProf);

        signupBox.setText("Sign Up To Penn Photo!");
        signupBox.setTitle("Sign Up Now!");
        signupBox.setAnimationEnabled(true);
        signupBox.setGlassEnabled(true);
        signupPanel.add(closeButtonPanel);
        signupPanel.add(signupGrid);
        stuProfOptions.add(stuProfGrid);
        signupPanel.add(stuProfOptions);
        signupPanel.add(signupButton);
        signupBox.add(signupPanel);

        closeButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                signupBox.hide();
            }
        });

        signupButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                if (stuProf.getSelectedIndex() == 0) {
                    signUp(firstName.getText(), lastName.getText(),
                            email.getText(), dob.getText(), gender.getText(),
                            0, year.getText(), major.getText(), GPA.getText(),
                            studentCollege.getText());
                } else {
                    signUp(firstName.getText(), lastName.getText(),
                            email.getText(), dob.getText(), gender.getText(),
                            1, office.getText(), researchArea.getText(),
                            title.getText(), professorCollege.getText());

                }
            }
        });

        return signupBox;
    }

    protected void signUp(String fN, String lN, String email, String dob,
            String gender, final int userType, final String arg1,
            final String arg2, final String arg3, final String arg4) {

        AsyncCallback<String> callback = new AsyncCallback<String>() {
            public void onFailure(Throwable caught) {

            }

            public void onSuccess(final String uid) {
                Window.alert("Welcome to Penn Photo! Your userID is " + uid);
                AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {

                    public void onSuccess(Boolean b) {
                        signupBox.hide();
                        userid = Integer.parseInt(uid);
                        loginPanel.clear();
                        drawHomepage();
                    }

                    public void onFailure(Throwable caught) {
                        // TODO Auto-generated method stub

                    }
                };
                if (userType == 0) {
                    updateService.addStudent(Integer.parseInt(uid),
                            Integer.parseInt(arg1), arg2,
                            Float.parseFloat(arg3), arg4, callback);
                } else {
                    updateService.addProfessor(Integer.parseInt(uid), arg1,
                            arg2, arg3, arg4, callback);
                }
            }
        };
        // updateService.addUser("test2", "test2", "test2@test.com",
        // "1987-02-03", "M", callback);
        updateService.addUser(fN, lN, email, dob, gender, callback);

    }

    private void drawHomepage() {
        // load content

        loadRecentUpdates();

        loadFriendRecommendations();

        loadTopPhotos();

        // assemble content widgets

        userPhotosScrollPanel.add(userPhotos);

        userPage.add(userHeaderBar);
        userPage.add(userContent);
        
        userContent.addWest(userInfoColumn, 250);
        userContent.add(userPhotosScrollPanel);
        
        userPage.setWidgetTopHeight(userHeaderBar, 0, Unit.EM, 3, Unit.EM);
        userPage.setWidgetTopBottom(userContent, 3, Unit.EM, 0, Unit.EM);

        friendListScrollPanel.add(friendList);

        userInfoColumn.add(userInfoTable);
        
        recentUpdatesScrollPanel.add(recentUpdates);
        
        topPhotosScrollPanel.add(topPhotos);
        
        recomScrollPanel.add(recomTable);
        
        // assemble page widgets

        headerBar.add(gotoHome);
        headerBar.add(gotoTopPhotos);
        headerBar.add(gotoFriends);
        headerBar.add(gotoFriendNetwork);
        headerBar.add(gotoSearch);
        headerBar.add(gotoAddPhoto);
        //headerBar.add(new Image("Upic_logo.png"));
        
        headerBar.setWidgetLeftWidth(headerBar.getWidget(0), 0, Unit.EM, 10, Unit.EM);
        headerBar.setWidgetLeftWidth(headerBar.getWidget(1), 10, Unit.EM, 10, Unit.EM);
        headerBar.setWidgetLeftWidth(headerBar.getWidget(2), 20, Unit.EM, 10, Unit.EM);
        headerBar.setWidgetLeftWidth(headerBar.getWidget(3), 30, Unit.EM, 10, Unit.EM);
        headerBar.setWidgetLeftWidth(headerBar.getWidget(4), 40, Unit.EM, 10, Unit.EM);
        headerBar.setWidgetLeftWidth(headerBar.getWidget(5), 50, Unit.EM, 10, Unit.EM);
        //headerBar.setWidgetRightWidth(headerBar.getWidget(6), 0, Unit.EM, 10, Unit.EM);

        feedBar.add(new Label("Suggested Friends"));
        feedBar.add(recomScrollPanel);
        feedBar.add(new Label("Recent Posts"));
        feedBar.add(recentUpdatesScrollPanel);

        feedBar.setWidgetTopHeight(feedBar.getWidget(0), 0, Unit.EM, 2, Unit.EM);
        feedBar.setWidgetTopHeight(feedBar.getWidget(1), 2, Unit.EM, 12, Unit.EM);
        feedBar.setWidgetTopHeight(feedBar.getWidget(2), 12, Unit.EM, 14, Unit.EM);
        feedBar.setWidgetTopBottom(feedBar.getWidget(3), 14, Unit.EM, 0, Unit.EM);

        footerBar.add(new Label("(c) 2011 UPic"));

        // assemble main panel

        DockLayoutPanel appPanel = new DockLayoutPanel(Unit.PCT);

        appPanel.addNorth(headerBar, 4);

        appPanel.addSouth(footerBar, 4);

        appPanel.addEast(feedBar, 20);

        appPanel.add(centerContent);

        RootLayoutPanel.get().add(appPanel);

        // add event handlers

        gotoTopPhotos.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {

                loadTopPhotos();

            }

        });

        gotoFriends.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {

                loadFriends();

            }

        });

        gotoFriendNetwork.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {

                loadFriendNetwork();

            }

        });

        gotoHome.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {

                loadUserPage(userid);

            }

        });

        gotoSearch.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {
                loadSearch();

            }
        });

        gotoAddPhoto.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {
                loadAddPhoto();

            }
        });

        populateOracle();
    }

    public void addFriend(String fid) {
        System.out.println("Adding friend");

        AsyncCallback<String> callback = new AsyncCallback<String>() {

            public void onFailure(Throwable caught) {
                System.out.println("Adding friend failure");

            }

            public void onSuccess(String result) { // TODO Auto-generated method
                System.out.println("Success");

            }
        };

        System.out.println("callback made");
        System.out.println(userid + " " + Integer.parseInt(fid) + " ");
        updateService.addFriend(userid, Integer.parseInt(fid), "default",
                callback);

    }

    private VerticalPanel buildPhotoFrame(final int pid, String url, String text) {

        VerticalPanel photoFrame = new VerticalPanel();
        Image photo = new Image(url);
        photo.setSize("100%", "100%");
        photo.setTitle(text);
        final FlowPanel tagsPanel = new FlowPanel();
        final SuggestBox tagBox = new SuggestBox(oracle);

        final AsyncCallback<Relation> populateTags = new AsyncCallback<Relation>() {

            public void onFailure(Throwable caught) {
            }

            public void onSuccess(Relation r) {
                tagsPanel.clear();
                Iterator<Tuple> i = r.iterator();
                while (i.hasNext()) {
                    Tuple t = i.next();
                    tagsPanel.add(new Button(t.getValue("tag").toString()));
                }
            }
        };

        tagBox.addKeyPressHandler(new KeyPressHandler() {
            public void onKeyPress(KeyPressEvent event) {
                if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
                    addTag(tagBox.getText(), pid);
                }
                queryService.getPhotoTags(Integer.toString(pid), populateTags);
            }
        });

        HorizontalPanel ratingPanel = new HorizontalPanel();

        final ListBox lb = new ListBox();

        lb.addItem("1");
        lb.addItem("2");
        lb.addItem("3");
        lb.addItem("4");
        lb.addItem("5");
        lb.setVisibleItemCount(1);
        lb.addChangeHandler(new ChangeHandler() {
            public void onChange(ChangeEvent event) {
                changeRating(userid, pid, lb.getValue(lb.getSelectedIndex()));
            }

        });

        ratingPanel.add(lb);
        photoFrame.add(photo);
        photoFrame.add(ratingPanel);
        photoFrame.add(tagBox);
        photoFrame.add(tagsPanel);

        queryService.getPhotoTags(Integer.toString(pid), populateTags);

        return photoFrame;
    }

    protected void changeRating(int uid, int pid, String rating) {
        System.out.println("Changing rating to " + rating + "for user " + uid
                + "on pic " + pid);
        /*
         * updateService.addRating(uid, pid, Integer.parseInt(rating), new
         * AsyncCallback<String>() {
         * 
         * public void onFailure(Throwable caught) { // TODO Auto-generated
         * method stub
         * 
         * }
         * 
         * public void onSuccess(String result) { // TODO Auto-generated method
         * stub
         * 
         * }
         * 
         * });
         */

    }

    protected void addTag(String text, int pid) {
        oracle.add(text);
        updateService.addTag(pid, text, new AsyncCallback<String>() {

            public void onFailure(Throwable caught) {
                caught.printStackTrace();

            }

            public void onSuccess(String result) {
                System.out.println(result);

            }

        });

    }

    private void populateOracle() {
        oracle = new MultiWordSuggestOracle();

        AsyncCallback<ArrayList<String>> callback = new AsyncCallback<ArrayList<String>>() {

            public void onFailure(Throwable caught) {
                System.out.println("fail.");

            }

            public void onSuccess(ArrayList<String> result) {
                for (String s : result) {
                    oracle.add(s);
                }

            }
        };

        queryService.getAllTags(callback);

    }

    public void drawNodeAndNeighbors(int person) {
        System.out.println("Requesting data for " + person);

        queryService.getFriendsVisualizerXML(person,
                new AsyncCallback<String>() {

                    public void onFailure(Throwable caught) {
                        // TODO Auto-generated method stub

                    }

                    public void onSuccess(String result) {
                        Node n = XMLandJSON.parseXML(result);

                        if (n != null) {
                            FriendVisualization.addToGraph(theGraph, XMLandJSON
                                    .getJsonForUser(n).toString());
                        }
                    }
                });

    }

    public void getFirstPerson() {
        AsyncCallback<String> callback = new AsyncCallback<String>() {

            public void onFailure(Throwable caught) {
                // TODO Auto-generated method stub

            }

            public void onSuccess(String result) {

                try {
                    JSONObject x = XMLandJSON.getJsonForUser(XMLandJSON
                            .parseXML(result));
                    if (x != null) {
                        // System.out.println(x.toString());
                        theGraph = FriendVisualization.createGraph(
                                x.toString(), testHomepage2.this);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };

        queryService.getFriendsVisualizerXML(userid, callback);
    }

    private void refreshSearchPanel() {
        VerticalPanel search = new VerticalPanel();
        final VerticalPanel results = new VerticalPanel();
        // results.setWidth("300px");
        final TextBox searchBox = new TextBox();

        searchBox.addKeyUpHandler(new KeyUpHandler() {

            public void onKeyUp(KeyUpEvent event) {
                if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
                    fireSearch(searchBox.getText(), results);
                }

            }

        });
        Button searchButton = new Button("Search");
        searchButton.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {
                fireSearch(searchBox.getText(), results);

            }
        });

        search.add(searchBox);
        search.add(searchButton);

        ScrollPanel resultsScrollable = new ScrollPanel();
        resultsScrollable.add(results);

        VerticalPanel scrollContainer = new VerticalPanel();
        scrollContainer.add(resultsScrollable);

        searchPanel.add(search);
        searchPanel.add(scrollContainer);

        resultsScrollable.setSize("700px", "500px");

    }

    private void fireSearch(String keywords, final VerticalPanel results) {

        AsyncCallback<Relation> callback = new AsyncCallback<Relation>() {
            public void onFailure(Throwable caught) {

            }

            public void onSuccess(Relation r) {
                results.clear();
                if (r.isEmpty()) {
                    results.add(new HTML(
                            "Sorry, no results were found for that query"));
                    return;
                }
                Iterator<Tuple> i = r.iterator();
                while (i.hasNext()) {
                    Tuple t = i.next();
                    Image im = new Image();
                    im.setUrl(t.getValue("url").toString());
                    results.add(im);
                    int old = im.getWidth();
                    im.setWidth("100%");
                    int newNum = Math.min(old, im.getWidth());
                    String newWidth = Integer.toString(newNum) + "px";
                    im.setWidth(newWidth);
                }
            }
        };

        queryService.getSearchedPhotos(keywords, Integer.toString(userid),
                callback);
    }
}
